很簡單啦,你就Draw.io畫一畫就好了啦
想必有部分的朋友一定有聽過自家前輩或是社群中的大神這樣子說過。
但愛因斯坦說的才能不足以研究數學轉而決定研究物理,跟吾等凡夫俗子能比嗎?
關於系統的設計想必大部分的朋友都一定有這種困擾,雖然各式各樣的開發模式與設計模式舉凡:Module Theory, The Module Pattern, The Facade Pattern…etc。
我們得到了心法,但該怎麼出招?這些心法如何落實在我想要的系統上?我的功能該放哪個資料夾?我該怎麼管理我的功能層級?
在我進行這部分的研究與探索的時候,絕大多數都是找到整個商務系統的設計規劃,在整個前端的流程設計上Kevin Pennekamp( 2021)在《How to create a scalable and maintainable front-end architecture》主張high-level architecture的設計上可以參照domain-driven development (DDD) 、separation of concerns (SoC)兩種風格。
而Jobayer Ahmmed(2020)則是整理歸納出三種層級Core、Shared、 Feature管理的要點,而這三種層級在C# .NET的開發上也有一樣的概念Core、Controller、Service。
雖然三層級管理的初始宣傳與公告已不可考(或者我菜找不到QQ,但我在猜應該是Angular官方團隊進行倡導),但我覺得就目前我所吸收到到的資訊來說Jobayer的詮釋最清晰,因為寫得太好了,我這邊直接貼上來跟大家分享,對於Core、Shared、 Feature的定義他是這樣子解釋的:
Core Module
- This module gets loaded with the app.
- Will contain singleton items - items that will be instantiated only once throughout the app or used in only one place.
- Will be imported only once by AppModule, no other feature module will import this module.
- You may put the following items in core module (you may put others if you see fit).
models: models that are used in several feature modules.
components: authentication, profile, header, footer, layout, home, error, dialog etc.
services: singleton services that will be used by several feature modules, i.e. log, storage, shared, modal, authentication, file, spinner etc.
Shared Module
- Contains commonly used directives, pipes and components that are re-used and referenced by components of feature modules.
- Imported by core module and other feature modules.
imports: CommonModule, RouterModule, FormsModule, ReactiveFormsModule, Material modules and other library modules.
declarations: components that will be re-used in different feature modules, i.e. HexadecimalCellEditorComponent.
exports: all imported and declared items.
providers: no services should be provided in this module.
Feature Module
Declare models, components, services and other items that will be only used within this module.
And for each feature module, you can also create a routing module.
在這段內容中我最重要的是,定義了什麼內容該放到core的這個層級資料夾之中:
什麼意思呢? 就是我整個系統初始化服務時,有些資料與邏輯對於整個系統來說是僅須也必須載入一次的項目,少了對於系統來說可能無法運行或不好進行狀態管理,多了可能導致載入衝突與不好進行狀態初始化管理。
這邊用我畫的Draw.io比較直觀
對於我而言,store與interception都是僅有一次載入並不斷地進行更新,所以它們在我的理解之中便是處於core的層級之中。
sotre將資料儲存在記憶體中,每一次的頁面重整都會把他洗掉
另外會放在core的還有一個初始化的routing,他僅作用在系統初始化的路由上,並經由這個路由Module進行前端Layout template的管理
在Shared的這邊所囊括的範圍就更多了,只要在複數地方進行引用,理論上來說都是需要放在Shared這個層級之中,舉凡型別的Type、enum與全域const、自定義的pipe與directive到共用的Component( Ex: app-form-input-text
)與Service都是在這個層級之中。
這裡的共用層級指的是"系統層級"也就是說假如在兩個不同的Feature分支中有著一樣的功能,這個功能就應該封裝成一個Component並丟到shared>components中進行管理,假如有微妙的差異呢?這邊給個KeyWord:NgInput,然後賣個關子。
接下來來到對於前端開發較為重要的一個層級: Feature。
為什麼會說重要呢? 假如身為後端與全端開發者的你,在Core與Shred的參照上一定會有其語感與熟悉感,但到了Feature這裡的邏輯依我的經驗就跟系統邏輯比較沒關係,而是跟業務邏輯與使用者操作情境有著較大的關係。
誠如API是系統與介面的服務生,前端系統更像是桌邊服務生或是領班或是管家,這意味著前端的feature必續更加貼近使用者操作情境,作為前端開發必須更加深入的理解業務邏輯,並依照不同的需求進行Feature切分設計。
以下用一個系統最常見的Feature-SystemManagement進行說明。
對於一個基礎系統來說,首先我們至少有著使用者相關功能-新增/編輯/刪除(停用)
假如我是用後端開發前端的思維進行開發的話,我可能就會將Template出來的Page視為終點,在這邊的層級就會是平面的
Paging/
| |-userCreat.html
| |-userEdit.html
| |-userDeleate.html
看起來還好對吧? 那假如我在系統管理的功能上開了新功能叫做權限管理,讓系統操作人員能夠設定每個使用的可以進行的權限腳色(以公司的角度來說可能就是總經理>區經理>經理>協理>組長>一般職員>工讀生),這邊也簡單用新增/編輯/刪除(停用)作範例。
這時候Paging就變成了。
Paging/
| |-userCreat.html
| |-userEdit.html
| |-userDeleate.html
| |-roleCreat.html
| |-roleEdit.html
| |-roleDeleate.html
這樣子的管理對於對於以後端的角度以及新進前端開發人員是常見的,但一旦專案功能一旦成長起來對於整個脈絡會是全靠老師傅的經驗與靈感了,也只有專門一直開發與維護這個專案或產品的他對於某個需求在哪個犄角旮旯裡有著深刻的認知。
但對於要接手維護的我們,只能是臉上笑嘻嘻了
另外假如我們開發了這樣子的專案一段時間,中間被抓去支援其他專案或產品開發後,在回來看這個案子時,我不敢保證我一定能認出每個命名代表的意涵究竟是什麼,究竟是客戶臨時改功能意涵還是自己的英文爛亂命名,一切的一切只有神知道了。
但假如換成依照業務情境進行開發的話,就會變成以下層級。
systemManagement/
| |-UserManagement
| | |-createUser
| | |-editUser
| | |-deleateUser
| |-roleManagement
| | |-createUser
| | |-editUser
| | |-deleateUser
這樣子的層級不但清晰明瞭,更能直觀的想像他的路由情境與使用者可能的操作情境,在某些功能的擴充與移除上也顯得更加簡易,我可以透過移除路由進行軟廢止,再透過逐步移除功能Function完全廢除功能。
在整個前端系統開發的過程中,我們必須緊抓User Story來進行開發,同時必須與後端所提供的API達到良好的互動與應用。
假如你已經有了這樣子的認知與一些模糊的概念,恭喜你,我們學會了一種開發模式叫做DDD( Domain-Driven Design )
DDD <=> Domain-Driven Design
他的兄弟與前輩們也包括TDD ( Test-driven Development ) 與BDD (Behavior-driven Development )
一個電商網站他一定會有顧客、上架店家兩種角色以及我們進行管理整個電商的系統平台。
再舉個例子,物流追蹤系統的話他的角色可能就會有物流配送人員、物流系統監測人員,公司人員
兩個例子其實都是想要跟大家說,前端開發者在開發過程中必須更加思考使用者情境與業務邏輯,在系統的各項功能層級設計上要緊抓使用者的操作情境。
那麼我們已經開始了一個基礎電商的商品首頁了 明天我們即將進行在許久以前所提到的Scss渲染引擎-TailwindCss